package dbexp.model;

import static dbexp.model.db.DbOT.COLUMN;

import java.sql.Types;

import dbexp.connection.DbConnection;

public class Column extends DbObject {
	private static final long serialVersionUID = 1L;
	private int action = DbConnection.CREATE;

	public Column() {

	}

	public Column(String name, String schema, String table) {
		super(name, schema, COLUMN);
		setTable(table);
	}

	public String getName() {
		if (getLabel() != null) {
			return getLabel();
		}
		return super.getName();
	}

	public void setTable(String t) {
		set("TABLE", t);
	}

	public String table() {
		return getString("TABLE");
	}

	public void setLabel(String name) {
		set("LABEL", name);
	}

	private String getLabel() {
		return getString("LABEL");
	}

	public void setDataType(String dt) {
		set("TYPE", dt);
	}

	public String getDataType() {
		return getString("TYPE");
	}

	public void setSqlType(int dt) {
		set("SQL_TYPE", dt);
	}

	public int sqlType() {
		return getInt("SQL_TYPE");
	}

	public void setDataSize(long l) {
		set("SIZE", l);
	}

	public long getSize() {
		return getLong("SIZE");
	}

	/**
	 * Ustawia wielkość części dziesiętnej
	 * 
	 * @param scale
	 */
	public void setDataScale(String scale) {
		set("SCALE", scale);
	}

	/**
	 * Pobiera wielkość części dziesiętnej
	 * 
	 * @return scale
	 */
	public long getScale() {
		return getLong("SCALE");
	}

	public void setNullable(boolean ds) {
		set("NULLABLE", ds);
	}

	public boolean isNullable() {
		return is("NULLABLE");
	}

	public void setDataDefault(String dd) {
		set("DEFAULT", dd);
	}

	public String getDefault() {
		return getNNString("DEFAULT");
	}

	public void setAction(int action) {
		this.action = action;
	}

	public int getAction() {
		return this.action;
	}

	public String getQuery(int operation) {
		return null;
	}

	public String getFormattedDataType() {

		String typeString = getDataType() == null ? "" : getDataType();

		StringBuilder buffer = new StringBuilder(typeString);

		int _type = sqlType();
		if (_type == 0) {
			_type = getSqlType(typeString);
		}
		if (!typeString.matches("\\b\\D+\\d+\\b")
				|| (_type == Types.CHAR || _type == Types.VARCHAR || _type == Types.LONGVARCHAR)) {

			if (getSize() > 0 && !isDateDataType() && !isNonPrecisionType()) {
				buffer.append("(");
				buffer.append(getSize());

				if (getScale() > 0) {
					buffer.append(",");
					buffer.append(getScale());
				}
				buffer.append(")");
			}
		}
		return buffer.toString();
	}

	public int getSqlType(String dt) {
		if (dt.equalsIgnoreCase("VARCHAR2")) {
			return Types.VARCHAR;
		} else if (dt.equalsIgnoreCase("NVARCHAR2")) {
			return Types.VARCHAR;
		} else if (dt.equalsIgnoreCase("CHAR")) {
			return Types.CHAR;
		} else if (dt.equalsIgnoreCase("NCHAR")) {
			return Types.CHAR;
		} else if (dt.equalsIgnoreCase("NUMBER")) {
			return Types.NUMERIC;
		}
		return 0;
	}

	public boolean isDateDataType() {
		int _type = sqlType();
		return _type == Types.DATE || _type == Types.TIME
				|| _type == Types.TIMESTAMP;
	}

	public boolean isNonPrecisionType() {
		return sqlType() == Types.BIT;
	}

	public boolean equals(Object obj) {
		if (obj instanceof Column) {
			if (((Column) obj).getName().equalsIgnoreCase(getName())) {
				return true;
			}
		}
		return super.equals(obj);
	}

	public void setPK(boolean pkv) {
		set("PK", pkv);
	}

	public boolean isPK() {
		return is("PK");
	}

	public boolean isCurrency(Object o) {
		return o.toString().matches(currencyRegex);
	}

	public boolean isNumber(Object o) {
		return o.toString().matches(numberRegex);
	}

	public static final String currencyRegex = "^[ -]?[0-9]+( ?[0-9]{3})*([,.][0-9]?[0-9])?{1}$";
	public static final String numberRegex = "^[ -]?([0-9])+$";
}
